package user

import (
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"end/config"
	"end/entry"
	"end/httpEntry"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	"io"
	"net/http"
	"strconv"
	"time"
)

const appID = "wxd6ad672beb698488"
const appSecret = "6642916c92dd5832b3a5294922230d95"

type LoginRequest struct {
	Name     string `json:"name" binding:"required"`
	Password string `json:"password" binding:"required"`
}

type LoginResponse struct {
	Code    int                 `json:"code"`
	Token   string              `json:"token"`
	Error   string              `json:"error"`
	Message string              `json:"message"`
	Type    []config.Additional `json:"type"`
}

type OrderRequest struct {
	Status int `json:"status"`
	Page   int `json:"page"`
}

type UpdateRequest struct {
	Phone             string `json:"phone"`
	Nick              string `json:"nick"`
	Img               string `json:"img"`
	Age               int    `json:"age"`
	PoliticalOutlook  string `json:"political_outlook"`
	Address           string `json:"address"`
	PersonalSignature string `json:"personal_signature"`
	IdNumber          string `json:"id_number"`
}

func IsLogin(r *gin.Engine) {
	r.GET("/is/login", httpEntry.LoginMiddleware(), func(context *gin.Context) {
		context.JSON(http.StatusOK, httpEntry.BaseResponse{
			Code:    200,
			Message: "登录成功",
		})
		return
	})
}

func Login(r *gin.Engine) {
	type WechatSessionResponse struct {
		OpenID string `json:"openid"`
		// 根据需要，可以添加其他字段，例如 session_key, unionid 等
	}

	r.POST("/user/login", func(context *gin.Context) {
		var userRequest LoginRequest
		err := context.BindJSON(&userRequest)

		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}

		// 创建一个MD5哈希对象
		hashes := md5.New()
		// 将字符串写入哈希对象
		hashes.Write([]byte(userRequest.Password))
		// 计算哈希值并将其转换为16进制字符串
		hashInBytes := hashes.Sum(nil)
		hashPassword := hex.EncodeToString(hashInBytes)

		db := config.GetDb()
		var user entry.User
		result := db.Where("name = ? AND password = ?", userRequest.Name, hashPassword).First(&user)
		// 检查错误
		if result.Error != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10005,
				Error: httpEntry.ERROR10005,
			})
			return
		}
		token, additionals := config.CreateToken(user.ID)
		userResponse := LoginResponse{
			Code:    200,
			Message: "登录成功",
			Token:   token,
			Type:    additionals,
		}
		context.JSON(http.StatusOK, userResponse)
	})

	r.GET("/user/login/wx2/:jsCode", func(context *gin.Context) {
		jsCode := context.Param("jsCode")
		url := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", appID, appSecret, jsCode)
		// 发起HTTP GET请求
		resp, err := http.Get(url)
		if err != nil {
			return
		}
		defer func(Body io.ReadCloser) {
			err := Body.Close()
			if err != nil {

			}
		}(resp.Body)
		// 读取响应内容
		body, err := io.ReadAll(resp.Body)
		if err != nil {
			return
		}

		// 解析JSON数据
		var wechatResp WechatSessionResponse
		err = json.Unmarshal(body, &wechatResp)
		if err != nil {
			return
		}
		db := config.GetDb()
		var user entry.User
		result := db.Where("openid = ?", wechatResp.OpenID).First(&user)
		// 检查错误
		if result.Error != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10005,
				Error: httpEntry.ERROR10005,
			})
			return
		}
		// 解析用户模块
		token, additionals := config.CreateToken(user.ID)
		userResponse := LoginResponse{
			Code:    200,
			Message: "登录成功",
			Token:   token,
			Type:    additionals,
		}
		context.JSON(http.StatusOK, userResponse)
	})

	r.POST("/user/login/wx/:openid", func(context *gin.Context) {
		openid := context.Param("openid")

		db := config.GetDb()
		var user entry.User
		result := db.Where("openid = ?", openid).First(&user)
		// 检查错误
		if result.Error != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10005,
				Error: httpEntry.ERROR10005,
			})
			return
		}
		// 解析用户模块
		token, additionals := config.CreateToken(user.ID)
		userResponse := LoginResponse{
			Code:    200,
			Message: "登录成功",
			Token:   token,
			Type:    additionals,
		}
		context.JSON(http.StatusOK, userResponse)
	})
}

// AllUser 所有用户
func AllUser(r *gin.Engine) {
	r.GET("/user/all/:page", httpEntry.LoginMiddleware(), httpEntry.Admin1Middleware(), func(context *gin.Context) {
		pageStr := context.Param("page")
		page, err := strconv.Atoi(pageStr)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
		}
		db := config.GetDb()
		var users []entry.User

		db.Offset((page - 1) * 40).Limit(40).Order("integral desc").Find(&users)
		// 清空全部密码
		for i := range users {
			users[i].Password = ""
		}
		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "成功",
			"data":    users,
		})
	})
}

type MeInfo struct {
	entry.User
	ActivityNum int64 `json:"activity_num"`
}

// GetMeInfo 获取自己详细信息
func GetMeInfo(r *gin.Engine) {
	r.GET("/user/info", httpEntry.LoginMiddleware(), func(context *gin.Context) {
		userinfo := context.MustGet("userinfo").(config.UserInfo)
		allinfo := context.MustGet("allinfo").(config.AllInfo)
		db := config.GetDb()
		var user entry.User
		var meInfo MeInfo

		db.Where("id = ?", userinfo.Id).First(&user)
		err := copier.Copy(&meInfo, &user)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		var activityNum int64
		db.Model(entry.Eventregistration{}).Where("userid = ?", userinfo.Id).Count(&activityNum)
		meInfo.ActivityNum = activityNum
		user.Password = ""
		user.OpenID = ""
		var business entry.Business
		err = db.Where("userid = ?", userinfo.Id).First(&business).Error
		if err != nil {
			context.JSON(http.StatusOK, gin.H{
				"code":     200,
				"message":  "获取成功",
				"data":     meInfo,
				"allinfo":  allinfo,
				"business": map[string]interface{}{},
			})
			return
		}
		context.JSON(http.StatusOK, gin.H{
			"code":     200,
			"message":  "获取成功",
			"data":     meInfo,
			"allinfo":  allinfo,
			"business": business,
		})
	})
}

// DelMeBusiness 删除自己商家信息
func DelMeBusiness(r *gin.Engine) {
	r.GET("/user/del/business", httpEntry.LoginMiddleware(), func(context *gin.Context) {
		userinfo := context.MustGet("userinfo").(config.UserInfo)
		db := config.GetDb()
		var business entry.Business
		err := db.Where("userid = ?", userinfo.Id).First(&business).Error
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10005,
				Error: httpEntry.ERROR10005,
			})
			return
		}
		if business.Status&httpEntry.STATUS2 != 0 {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10011,
				Error: httpEntry.ERROR10011,
			})
			return
		}
		// 删除
		db.Delete(&business)
		context.JSON(http.StatusOK, httpEntry.BaseResponse{
			Code:    200,
			Message: "操作成功",
		})
	})
}

type OrderDto struct {
	ID          int             `json:"id" gorm:"column:id"`
	CommodityID int             `json:"commodityid" gorm:"column:commodityid"`
	CreateTime  time.Time       `json:"createtime" gorm:"column:createtime"`
	UserID      int             `json:"userid" gorm:"column:userid"`
	Status      string          `json:"status" gorm:"column:status"`
	Businessid  int             `json:"businessid" gorm:"column:businessid"`
	UpdateTime  time.Time       `json:"updatetime" gorm:"column:updatetime"`
	Commodity   entry.Commodity `json:"commodity" gorm:"foreignKey:CommodityID"`
}

func (OrderDto) TableName() string {
	return "order"
}

type AllOrderRequest struct {
	Page   int  `json:"page" binding:"required"`
	Status *int `json:"status" binding:"required"`
}

// AllOrder 用户全部订单
func AllOrder(r *gin.Engine) {
	r.POST("/user/order", httpEntry.LoginMiddleware(), func(context *gin.Context) {
		var allOrderRequest AllOrderRequest
		err := context.ShouldBind(&allOrderRequest)
		if err != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10006,
				Error: httpEntry.ERROR10006,
			})
			return
		}
		userinfo := context.MustGet("userinfo").(config.UserInfo)
		db := config.GetDb()
		var orders []OrderDto
		db.Preload("Commodity").Where("userid = ? and status & ?", userinfo.Id, allOrderRequest.Status).
			Offset((allOrderRequest.Page - 1) * 50).
			Limit(50).Find(&orders)
		context.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "获取成功",
			"data":    orders,
		})
	})
}

func UpdateUser(r *gin.Engine) {
	//用户信息修改
	r.POST("/user/update", httpEntry.LoginMiddleware(), func(c *gin.Context) {
		userinfo := c.MustGet("userinfo").(config.UserInfo)
		var request UpdateRequest
		err := c.BindJSON(&request)
		if err != nil {
			return
		}
		db := config.GetDb()
		toMap, err := config.UpdateToMap(&request)
		if err != nil {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		result := db.Model(&entry.User{}).Where("id = ?", userinfo.Id).Updates(toMap)
		if result.Error != nil {
			c.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		c.JSON(http.StatusOK, gin.H{
			"code":    200,
			"message": "更新成功",
		})
	})
}

type Dto struct {
	ID       int            `json:"id" gorm:"column:id"`
	Admin    entry.Admin    `gorm:"foreignkey:UserID"`
	Business entry.Business `gorm:"foreignkey:UserID"`
	Clerk    entry.Clerk    `gorm:"foreignkey:UserID"`
}

func (Dto) TableName() string {
	return "user"
}

// GetUserStatus 获取检测自己身份还有状态
func GetUserStatus(r *gin.Engine) {
	r.GET("/user/get/status", httpEntry.LoginMiddleware(), func(context *gin.Context) {
		userinfo := context.MustGet("userinfo").(config.UserInfo)
		if userinfo.Identity != "user" {
			context.JSON(http.StatusOK, gin.H{
				"code":     200,
				"identity": userinfo.Identity,
				"status":   httpEntry.STATUS2,
			})
			return
		}
		userid := userinfo.Id
		db := config.GetDb()
		var dto Dto
		result := db.Preload("Admin").
			Preload("Business").
			Preload("Clerk").Where("id = ?", userid).First(&dto)
		if result.Error != nil {
			context.JSON(http.StatusOK, httpEntry.BaseResponse{
				Code:  10014,
				Error: httpEntry.ERROR10014,
			})
			return
		}
		if dto.Admin.ID != 0 {
			context.JSON(http.StatusOK, gin.H{
				"code":     200,
				"identity": fmt.Sprintf("%s%d", "admin", dto.Admin.Power),
			})
		} else if dto.Business.ID != 0 {
			context.JSON(http.StatusOK, gin.H{
				"code":     200,
				"identity": "business",
				"status":   dto.Business.Status,
			})
		} else if dto.Clerk.ID != 0 {
			context.JSON(http.StatusOK, gin.H{
				"code":     200,
				"identity": "clerk",
				"status":   "已通过",
			})
		} else {
			context.JSON(http.StatusOK, gin.H{
				"code":     200,
				"identity": "user",
				"status":   "已通过",
			})
		}
	})
}

// SetIntegral 输入用户id，获取用户积分
func SetIntegral(r *gin.Engine) {

}
